//
//  Renderer.hpp
//  RayTracer
//
//  Created by 俞云康 on 2/15/16.
//  Copyright © 2016 yushroom. All rights reserved.
//

#ifndef Renderer_hpp
#define Renderer_hpp

#include "Math.hpp"
#include "Scene.hpp"
#include "Camera.hpp"
#include "Canvas.hpp"
#include "Integrator.hpp"
#include "Sample.hpp"
#include <thread>
#include <mutex>

class Renderer {
private:
    //int samples;
    //float invSamp;
    int mWidth;
    int mHeight;
    Color* p;
    const Scene* scene;
    const Camera* camera;
    //const SurfaceIntegrator* surf_integrator;
    shared_ptr<SurfaceIntegrator> surf_integrator;
    int ok = 0;
    float report_interval;
    
    int m_nCameraSamples = 2;
    int m_nIntegratorSamples = 2;

	std::mutex log_mutex;
    
public:
    Renderer() = default;
    
    Renderer(int    nCameraSamples,
             int    nIntegratorSamples,
             float  report_interval);
    
	static shared_ptr<Renderer> create(const Params& params);

    void init(int    nCameraSamples,
              int    nIntegratorSamples,
              float  report_interval) {
        m_nCameraSamples = nCameraSamples;
        m_nIntegratorSamples = nIntegratorSamples;
        this->report_interval = report_interval;
    }
    
    void render(const Scene&    scene,
                const Camera&   camera,
                Canvas&         canvas,
                shared_ptr<SurfaceIntegrator>
                                surf_integrator);
    
    void render_region(const Scene&     scene,
                       const Camera&    camera,
                       Canvas&          canvas,
                       shared_ptr<SurfaceIntegrator> surf_integrator,
                       float x, float y, float width, float height);
    
    void render_pixel(const Scene& scene,
                      const Camera& camera,
                      Canvas& canvas,
                      shared_ptr<SurfaceIntegrator> surf_integrator,
                      int x, int y);
    
    void render_paral(const int   x,
                      const int   y,
                      const int   w,
                      const int   h,
                      const ProgressReporter&
                                reporter);
    
    Color Li(const Scene&   scene,
             const Ray&     ray,
             Sampler&       sampler,
             RNG&           rng) const ;
};

#endif /* Renderer_hpp */
